package com.lkx.monitorconsole.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lkx.monitorconsole.entity.InterfaceVisitorRecord;
import com.lkx.monitorconsole.mapper.InterfaceVisitorRecordExtendMapper;
import com.lkx.monitorconsole.mapper.InterfaceVisitorRecordMapper;
import com.lkx.monitorconsole.params.InterfaceVisitorRecordParams;
import com.lkx.monitorconsole.params.InterfaceVisitorRecordQueryParams;
import com.lkx.monitorconsole.schedulers.InterfaceRecordScheduler;
import com.lkx.monitorconsole.service.IInterfaceVisitorRecordService;
import com.lkx.monitorconsole.utils.R;
import com.lkx.monitorconsole.vo.RecordCountVO;
import com.lkx.monitorconsole.vo.VisitorLimitCountVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author likaixuan
 * @since 2022-10-11
 */
@Slf4j
@Service
public class InterfaceVisitorRecordServiceImpl extends ServiceImpl<InterfaceVisitorRecordMapper, InterfaceVisitorRecord> implements IInterfaceVisitorRecordService {


    @Autowired
    private InterfaceVisitorRecordExtendMapper mapper;

    @Async
    @Override
    public R<String> asynAddList(InterfaceVisitorRecordParams params) {
        InterfaceVisitorRecord record = new InterfaceVisitorRecord();
        BeanUtils.copyProperties(params,record);
        record.setCreateTime(LocalDateTime.now());
        InterfaceRecordScheduler.list.add(record);
        return R.ok();
    }

    @Override
    public R<String> batchAdd(List<InterfaceVisitorRecord> records) {
        mapper.batchInsert(records);
        return R.ok();
    }

    @Override
    public R<RecordCountVO> queryLastlist() {
        RecordCountVO recordCountVO = new RecordCountVO();
        recordCountVO.setMinCount(queryRecordCount(1));
        recordCountVO.setHourCount(queryRecordCount(60));
        recordCountVO.setDayCount(queryRecordCount(24*60));
        recordCountVO.setMonCount(queryRecordCount(30*24*60));
        return R.ok(recordCountVO);
    }

    @Override
    public R<VisitorLimitCountVO> queryMinlist(InterfaceVisitorRecordQueryParams params) {
        //获取最近一分钟的每秒总访问量和限流量
        params=setTime(params,-1);
        List<VisitorLimitCountVO> list = mapper.selectMinList(params);


        List<VisitorLimitCountVO> tempList = new ArrayList<>();
        VisitorLimitCountVO vo;

        for (int i = 0; i <= 60; i++) {
            vo = new VisitorLimitCountVO();
            vo.setVisitorTime(DateUtils.addSeconds(new Date(),-i*1));
            String fomatDate = DateFormatUtils.format(vo.getVisitorTime(),"mm:ss");
            vo.setVisitorTimeStr(fomatDate);
            tempList.add(vo);
        }


        for (VisitorLimitCountVO visitorLimitCountVO : tempList) {
            for (VisitorLimitCountVO limitCountVO : list) {

                String date1 = DateFormatUtils.format(visitorLimitCountVO.getVisitorTime(),"yyyy-MM-dd HH:mm:ss");
                String date2 = DateFormatUtils.format(limitCountVO.getVisitorTime(),"yyyy-MM-dd HH:mm:ss");
                if(date1.equals(date2)){
                    if(limitCountVO.getStatus()==0){
                        visitorLimitCountVO.setCount(limitCountVO.getCount());
                    }else{
                        visitorLimitCountVO.setLimitCount(limitCountVO.getCount());
                    }
                    visitorLimitCountVO.setStatus(limitCountVO.getStatus());
                }
            }
        }

        return R.ok(tempList);
    }

    @Override
    public R<VisitorLimitCountVO> queryHourlist(InterfaceVisitorRecordQueryParams params) {
        //获取最近一小时的每分钟总访问量和限流量
        setTime(params,-60);
        List<VisitorLimitCountVO> list = mapper.selectHourList(params);


        List<VisitorLimitCountVO> tempList = new ArrayList<>();
        VisitorLimitCountVO vo;

        for (int i = 0; i <= 60; i++) {
            vo = new VisitorLimitCountVO();
            vo.setVisitorTime(DateUtils.addMinutes(new Date(),-i*1));
            String fomatDate = DateFormatUtils.format(vo.getVisitorTime(),"HH:mm");
            vo.setVisitorTimeStr(fomatDate);
            tempList.add(vo);
        }


        for (VisitorLimitCountVO visitorLimitCountVO : tempList) {
            for (VisitorLimitCountVO limitCountVO : list) {

                String date1 = DateFormatUtils.format(visitorLimitCountVO.getVisitorTime(),"yyyy-MM-dd HH:mm");
                String date2 = DateFormatUtils.format(limitCountVO.getVisitorTime(),"yyyy-MM-dd HH:mm");


                if(date1.equals(date2)){

                    if(limitCountVO.getStatus()==0){
                        visitorLimitCountVO.setCount(limitCountVO.getCount());
                    }else{
                        visitorLimitCountVO.setLimitCount(limitCountVO.getCount());
                    }
                    visitorLimitCountVO.setStatus(limitCountVO.getStatus());
                }
            }
        }
        return R.ok(tempList);
    }

    @Override
    public R<VisitorLimitCountVO> queryDaylist(InterfaceVisitorRecordQueryParams params) {
        //获取最近一天的每小时总访问量和限流量
        setTime(params,-60*24);
        List<VisitorLimitCountVO> list = mapper.selectDayList(params);


        List<VisitorLimitCountVO> tempList = new ArrayList<>();
        VisitorLimitCountVO vo;

        for (int i = 0; i <= 24; i++) {
            vo = new VisitorLimitCountVO();
            vo.setVisitorTime(DateUtils.addMinutes(new Date(),-i*60));
            String fomatDate = DateFormatUtils.format(vo.getVisitorTime(),"MM-dd HH");
            vo.setVisitorTimeStr(fomatDate);
            tempList.add(vo);
        }


        for (VisitorLimitCountVO visitorLimitCountVO : tempList) {
            for (VisitorLimitCountVO limitCountVO : list) {

                String date1 = DateFormatUtils.format(visitorLimitCountVO.getVisitorTime(),"yyyy-MM-dd HH");
                String date2 = DateFormatUtils.format(limitCountVO.getVisitorTime(),"yyyy-MM-dd HH");

                if(date1.equals(date2)){

                    if(limitCountVO.getStatus()==0){
                        visitorLimitCountVO.setCount(limitCountVO.getCount());
                    }else{
                        visitorLimitCountVO.setLimitCount(limitCountVO.getCount());
                    }
                    visitorLimitCountVO.setStatus(limitCountVO.getStatus());
                }
            }
        }
        return R.ok(tempList);
    }

    @Override
    public R<VisitorLimitCountVO> queryMonlist(InterfaceVisitorRecordQueryParams params) {
        //获取最近30天的每天总访问量和限流量
        setTime(params,-60*24*30);
        List<VisitorLimitCountVO> list = mapper.selectMonList(params);


        List<VisitorLimitCountVO> tempList = new ArrayList<>();
        VisitorLimitCountVO vo;

        for (int i = 0; i <= 30; i++) {
            vo = new VisitorLimitCountVO();
            vo.setVisitorTime(DateUtils.addMinutes(new Date(),-i*24*60));
            String fomatDate = DateFormatUtils.format(vo.getVisitorTime(),"MM-dd HH");
            vo.setVisitorTimeStr(fomatDate);
            tempList.add(vo);
        }



        for (VisitorLimitCountVO visitorLimitCountVO : tempList) {
            for (VisitorLimitCountVO limitCountVO : list) {

                String date1 = DateFormatUtils.format(visitorLimitCountVO.getVisitorTime(),"yyyy-MM-dd");
                String date2 = DateFormatUtils.format(limitCountVO.getVisitorTime(),"yyyy-MM-dd");
                if(date1.equals(date2)){
                    if(limitCountVO.getStatus()==0){
                        visitorLimitCountVO.setCount(limitCountVO.getCount());
                    }else{
                        visitorLimitCountVO.setLimitCount(limitCountVO.getCount());
                    }
                    visitorLimitCountVO.setStatus(limitCountVO.getStatus());
                }
            }
        }

        return R.ok(tempList);
    }

    @Override
    public R<VisitorLimitCountVO> querylist(InterfaceVisitorRecordQueryParams params) {
        if(params.getVisitorStartTime() == null || params.getVisitorEndTime() == null){
            return queryMinlist(params);
        }
        //得到相差多少分钟
        int minNum = differentMinByMillisecond(params.getVisitorStartTime(),params.getVisitorEndTime());
        //如果超过30天或则结束日期比开始日期早不处理
        if(minNum<0 || minNum>30*24*60){
            return R.error("日期超过30天或则结束日期比开始日期早");
        }

        return R.ok(commonQuery(params,minNum));
    }

    /**
     * 通过秒毫秒数判断两个时间的间隔的分钟
     * @param date1
     * @param date2
     * @return
     */
    public static int differentMinByMillisecond(Date date1,Date date2)
    {
        int min = (int) ((date2.getTime() - date1.getTime()) / (1000*60));
        return min;
    }

    private List<VisitorLimitCountVO> commonQuery(InterfaceVisitorRecordQueryParams params,int minNum){
        List<VisitorLimitCountVO> tempList = new ArrayList<>();
        VisitorLimitCountVO vo;
        String fomatDate = null;

        String pattern = null;

        int createNum = 0;
        if (minNum<=1){
            //一分钟之内的，按照秒级返回
            createNum = minNum*60;
        }else if(minNum>1 && minNum<=2*60){
            //大于一分钟小于2个小时的，按照分钟级返回
            createNum = minNum;
        }else if(minNum>2*60 && minNum<=24*60){
            //大于2个小时小于1天的，按照5分钟级返回
            createNum= minNum/5;
        }else if(minNum>24*60 && minNum<=30*24*60){
            //大于1天小于30天的，按照1小时级返回
            createNum= minNum/60;
        }
        for (int i = 0; i <= createNum; i++) {
            vo = new VisitorLimitCountVO();
            if (minNum<=1){
                //一分钟之内的，按照秒级返回
                vo.setVisitorTime(DateUtils.addSeconds(params.getVisitorEndTime(),-i*1));
                fomatDate = DateFormatUtils.format(vo.getVisitorTime(),"mm:ss");
                pattern = "yyyy-MM-dd HH:mm:ss";
            }else if(minNum>1 && minNum<=2*60){
                //大于一分钟小于2个小时的，按照分钟级返回
                vo.setVisitorTime(DateUtils.addMinutes(params.getVisitorEndTime(),-i*1));
                fomatDate = DateFormatUtils.format(vo.getVisitorTime(),"HH:mm");
                pattern = "yyyy-MM-dd HH:mm";
            }else if(minNum>2*60 && minNum<=24*60){
                //大于2个小时小于1天的，按照5分钟级返回
                getNewTime(params.getVisitorEndTime());
                vo.setVisitorTime(DateUtils.addMinutes(params.getVisitorEndTime(),-i*5));
                fomatDate = DateFormatUtils.format(vo.getVisitorTime(),"HH:mm");
                pattern = "yyyy-MM-dd HH:mm";
            }else if(minNum>24*60 && minNum<=30*24*60){
                //大于1天小于30天的，按照1小时级返回
                vo.setVisitorTime(DateUtils.addHours(params.getVisitorEndTime(),-i*1));
                fomatDate = DateFormatUtils.format(vo.getVisitorTime(),"MM-dd HH");
                pattern = "yyyy-MM-dd HH";
            }
            vo.setVisitorTimeStr(fomatDate);
            tempList.add(vo);
        }

        setTime(params,0);
        List<VisitorLimitCountVO> list = null;

        if (minNum<=1){
            //一分钟之内的，按照秒级返回
            list = mapper.selectMinList(params);
        }else if(minNum>1 && minNum<=2*60){
            //大于一分钟小于2个小时的，按照分钟级返回
            list = mapper.selectHourList(params);
        }else if(minNum>2*60 && minNum<=24*60){
            //大于2个小时小于1天的，按照5分钟级返回
            list = mapper.selectFiveMinList(params);
        }else if(minNum>24*60 && minNum<=30*24*60){
            //大于1天小于30天的，按照1小时级返回
            list = mapper.selectOneHourList(params);
        }


        for (VisitorLimitCountVO visitorLimitCountVO : tempList) {
            for (VisitorLimitCountVO limitCountVO : list) {

                String date1 = DateFormatUtils.format(visitorLimitCountVO.getVisitorTime(),pattern);
                String date2 = DateFormatUtils.format(limitCountVO.getVisitorTime(),pattern);
                if(date1.equals(date2)){
                    if(limitCountVO.getStatus()==0){
                        visitorLimitCountVO.setCount(limitCountVO.getCount());
                    }else{
                        visitorLimitCountVO.setLimitCount(limitCountVO.getCount());
                    }
                    visitorLimitCountVO.setStatus(limitCountVO.getStatus());
                }
            }
        }


        return tempList;
    }

    private Date getNewTime(Date date){
        int min = date.getMinutes();
        if(min%5>0){
            min = min/5*5;
            date.setMinutes(min);
        }
        return date;
    }


    private InterfaceVisitorRecordQueryParams setTime(InterfaceVisitorRecordQueryParams params,int date){
        if(params.getVisitorStartTime() != null && params.getVisitorEndTime() != null){
            params.setVisitorStartTime(params.getVisitorStartTime());
            params.setVisitorEndTime(params.getVisitorEndTime());
        }else{
            params.setVisitorStartTime(DateUtils.addMinutes(new Date(),date));
            params.setVisitorEndTime(new Date());
        }
        return params;
    }

    public Long queryRecordCount(int minus){
        LocalDateTime startTime = LocalDateTime.now().minusMinutes(minus);
        QueryWrapper queryWrapper = new QueryWrapper<InterfaceVisitorRecord>();
        queryWrapper.ge("visitor_time",startTime);
        return mapper.selectCount(queryWrapper);
    }

}
